package com.sven;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import java.util.ArrayList;
import java.util.List;

public class Test01 {

    public static void main(String[] args) {
        initFlowQpsRule();
        while (true){
            doSomething();
        }
    }

    //定义限流规则
    private static void initFlowQpsRule() {
        //可以看出规则是个链表，那么意味着可以一个资源对应多个规则
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        //规则设置资源名字，与SphU.entry保持一致
        rule1.setResource("doSomething");
        //设置流控的规则的以QPS为准，还有以线程为准
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //设置现在qps为20
        rule1.setCount(20);
        //根据调用方进行流量控制，默认就是全部生效
        // rule1.setLimitApp("default");
        rules.add(rule1);
        //添加进流控规则管理中
        FlowRuleManager.loadRules(rules);
    }

    //通过抛出异常的方式定义一个资源
   /* private  static void doSomething(){
        Entry entry = null;
        try {
            entry = SphU.entry("doSomething");
            //意味着通过，被保护的业务逻辑
            System.out.println("===========被保护的业务逻辑");
        } catch (BlockException e1) {
            //意味着限流了
            System.out.println("===========BlockException");
        } catch (Exception e2) {
            // 业务异常
            System.out.println("===========Exception");
        } finally {
            //确保这里一定要执行
            if (entry != null) {
                entry.exit();
                System.out.println("===========entry.exit()");
            }
        }
    }*/

    //通过返回布尔值的方式定义一个资源
    private  static void doSomething(){
        if(SphO.entry("doSomething")){
            try {
                //被保护的业务逻辑
                System.out.println("===========被保护的业务逻辑");
            }finally {
                //注意：这种方式中，资源使用完之后要调用exit()，否则会导致调用链异常，抛出ErrorEntryFreeException
                SphO.exit();
                System.out.println("===========SphO.exit()");
            }
        }else {
            //资源访问被限制
            System.out.println("===========资源访问被限制");
        }
    }

}
